package com.johnsoft.pph;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.johnsoft.util.ZIP;

public class Setup {
	
	private int supportedVersionCount;
	private String[] versions = new String[0];
	private String installedVersion;
	private boolean isClient;
	
	public Setup() {
		supportedVersionCount = 0;
	}
	
	public void setVersionCount(int i) {
		supportedVersionCount = i;
		versions = new String[i];
	}
	
	public void setInstalledVersion(String s) {
		installedVersion = s;
	}
	
	public void setVersionHash(int i, String s) {
		if(i < versions.length && i >= 0) {
			versions[i] = s;
		}
	}
	
	public void setIsClient(boolean b) {
		isClient = b;
	}
	
	private String getMinecraftDir() {
		if(System.getProperty("os.name").toLowerCase().equals("linux"))
			return System.getProperty("user.home") + "\\.minecraft\\";
		else if (System.getProperty("os.name").toLowerCase().equals("mac"))
			return System.getProperty("user.home") + "\\Library\\Application Support\\minecraft\\";
		return System.getProperty("user.home") + "\\appdata\\roaming\\.minecraft\\";
	}
	
	public void grabJar() throws IOException {
		if(isClient) {
			File minecraftjar = new File(getMinecraftDir() + "bin\\minecraft.jar");
			byte[] jar = readFile(minecraftjar);
			writeFile(new File("minecraft.zip"), jar);
		} else {
			copyFile(new File("minecraft_server.jar"), new File("minecraft.zip"));
		}
	}
	
	public void restoreJar() throws IOException {
		if(isClient) {
			File minecraftjar = new File("minecraft.jar.zip");
			byte[] jar = readFile(minecraftjar);
			writeFile(new File(getMinecraftDir() + "bin\\minecraft.jar"), jar);
		} else {
			new File("minecraft_server.jar").delete();
			copyFile(new File("minecraft.jar.zip"), new File("minecraft_server.jar"));
		}
	}
	
	public static byte[] readFile(File f) {
		try {
			BufferedInputStream input = new BufferedInputStream(new FileInputStream(f));
			byte[] file = new byte[input.available()];
			input.read(file, 0, file.length);
			input.close();
			return file;
		} catch (IOException e) {
			e.printStackTrace();
			return new byte[] { };
		}
		
	}
	
	private void writeFile(File f, byte[] bytes) {
		try {
			BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(f));
			output.write(bytes, 0, bytes.length);
			output.close();
		} catch (IOException e) {
		}
	}
	
	public void detectMinecraftInstall() {
		try {
			//Added this so when it throws the file not found err it will record the version as not found. (Could also be done in catch area)
			installedVersion = "Minecraft not found";
			DataInputStream cab = new DataInputStream(new FileInputStream(getMinecraftDir() + "bin\\version"));
			//Skip NULL and Linebreak
			installedVersion = "";
			cab.skipBytes(2);
			for(int i = 0; i < 13; i++)
			{
				byte b = (byte)cab.readByte();
				installedVersion += (char)b;
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void installModLoader() throws IOException {
		File modloaderclass = new File("temp/ModLoader.class");
		if(modloaderclass.exists()) {
			InstallerThread.log("ModLoader Found, Skipping ModLoader Installation");
		} else {
			InstallerThread.log("ModLoader not found, Installing ModLoader...");
			String[] files = new File("pph/modloader/").list();
			for (int i = 0; i < files.length; i++) {
				copyFile(new File("pph/modloader/" + files[i]), new File("temp/" + files[i]));
			}
		}
	}
	
	public void installModLoaderMP() throws IOException {
		File mlmp = new File("temp/ModLoaderMP.class");
		File mlmod = new File("temp/mod_mod_ModLoaderMp.class");
		if(mlmp.exists() && mlmod.exists()) {
			InstallerThread.log("ModLoaderMP Found, Skipping ModLoaderMP Installation");
		} else {
			InstallerThread.log("ModLoaderMP not found, Installing ModLoaderMP...");
			String[] files = new File("pph/modloadermp/").list();
			for (int i = 0; i < files.length; i++) {
				copyFile(new File("pph/modloadermp/" + files[i]), new File("temp/" + files[i]));
			}
		}
	}
	
	public void installMod() throws IOException {
		installMod("pph/minecraft_jar/", "");
	}
	
	public void installMod(String s, String dest) throws IOException {
		String[] files = new File(s).list();
		for (int i = 0; i < files.length; i++) {
			if(new File(s + files[i]).isDirectory())
				installMod(s + files[i] + "/", dest + "/" + files[i]);
			else
				copyFile(new File(s + files[i]), new File("temp/" + dest + "/" + files[i]));
		}
	}
	
	private void copyFile(File src, File dest) throws IOException {
		System.out.println("Copying " + src.getAbsolutePath() + " to " + dest.getAbsolutePath());
		ZIP.createDirs(dest.getAbsolutePath());
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(src));
		BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
		byte[] data = new byte[in.available()];
		in.read(data, 0, data.length);
		out.write(data, 0, data.length);
		in.close();
		out.close();
	}
	
	public void removeMeta() {
		ZIP.deleteFolder(new File("temp/META-INF/"));
	}
	
	public boolean canInstall() {
		for (int i = 0; i < supportedVersionCount; i++) {
			if(versions[i].equals(installedVersion))
				return true;
		}
		return false;
	}
	
	public int getSupportedVersions() {
		return supportedVersionCount;
	}
	
	public boolean isClientMod() {
		return isClient;
	}
	
	public String getVersionHash(int i) {
		if(i < versions.length && i >= 0) 
			return versions[i];
		return "";
	}
	
	public String getInstalledVersion() {
		return installedVersion;
	}

}
